package com.yy.finvideoplayer.media

import android.content.Context
import android.media.AudioManager
import android.view.Surface
import android.view.SurfaceHolder
import tv.danmaku.ijk.media.player.IMediaPlayer

/**
 * @Description: IjkBaseMedia
 * @Author: yiw89
 * @CreateDate: 2025/9/1 14:00
 * @Version: 1.0
 */
abstract class IjkBaseMedia(iMediaCallback: IMediaCallback) :
    BaseMedia(iMediaCallback),
    IMediaPlayer.OnPreparedListener, IMediaPlayer.OnCompletionListener,
    IMediaPlayer.OnBufferingUpdateListener,
    IMediaPlayer.OnSeekCompleteListener, IMediaPlayer.OnErrorListener,
    IMediaPlayer.OnVideoSizeChangedListener,
    IMediaPlayer.OnInfoListener {
    var mediaPlayer: IMediaPlayer? = null

    override fun doPrepare(
        context: Context,
        url: String,
        headers: Map<String, String?>?,
        vararg objects: Any?
    ): Boolean {
        try {
            release()
            mediaPlayer = getMedia(context, url, headers, *objects)
            mediaPlayer!!.setOnPreparedListener(this@IjkBaseMedia)
            mediaPlayer!!.setOnVideoSizeChangedListener(this@IjkBaseMedia)
            mediaPlayer!!.setOnCompletionListener(this@IjkBaseMedia)
            mediaPlayer!!.setOnErrorListener(this@IjkBaseMedia)
            mediaPlayer!!.setOnInfoListener(this@IjkBaseMedia)
            mediaPlayer!!.setOnBufferingUpdateListener(this@IjkBaseMedia)

            mediaPlayer!!.isLooping = isLooping

            mediaPlayer!!.setAudioStreamType(AudioManager.STREAM_MUSIC)
            mediaPlayer!!.setScreenOnWhilePlaying(true)
            mediaPlayer!!.prepareAsync()
            return true
        } catch (e: Exception) {
            e.printStackTrace()
            onError(
                mediaPlayer,
                IMediaControl.MEDIA_ERROR_UNKNOWN,
                IMediaControl.MEDIA_ERROR_UNKNOWN
            )
            return false
        }

        //}  }).start();
    }

    @Throws(Exception::class)
    abstract fun getMedia(
        context: Context,
        url: String,
        headers: Map<String, String?>?,
        vararg objects: Any?
    ): IMediaPlayer?

    override fun setSurface(surface: Surface) {
        try {
            if (mediaPlayer != null) mediaPlayer!!.setSurface(surface)
            this.surface = surface
        } catch (e: Exception) {
            e.printStackTrace()
            iMediaCallback.onError(
                this,
                IMediaControl.MEDIA_ERROR_UNKNOWN,
                IMediaControl.MEDIA_ERROR_UNKNOWN
            )
        }
    }

    override fun setDisplay(surfaceHolder: SurfaceHolder?) {
        try {
            if (mediaPlayer != null) mediaPlayer!!.setDisplay(surfaceHolder)
            if (surfaceHolder != null) this.surface = surfaceHolder.surface
        } catch (e: Exception) {
            e.printStackTrace()
            iMediaCallback.onError(
                this,
                IMediaControl.MEDIA_ERROR_UNKNOWN,
                IMediaControl.MEDIA_ERROR_UNKNOWN
            )
        }
    }

    override fun doPlay() {
        if (!isPrepar) return
        mediaPlayer!!.start()
    }

    override fun doPause() {
        if (!isPrepar) return
        mediaPlayer!!.pause()
    }

    override fun seekTo(duration: Int) {
        if (!isPrepar) return
        mediaPlayer!!.seekTo(duration.toLong())
    }

    override fun getCurrentPosition(): Int {
        if (!isPrepar) return 0
        try {
            return mediaPlayer!!.currentPosition.toInt()
        } catch (e: Exception) {
            e.printStackTrace()
            return 0
        }
    }

    override fun getDuration(): Int {
        if (!isPrepar) return 0
        try {
            return mediaPlayer!!.duration.toInt()
        } catch (e: Exception) {
            e.printStackTrace()
            return 0
        }
    }

    override fun getVideoHeight(): Int {
        if (!isPrepar) return 0
        return mediaPlayer!!.videoHeight
    }

    override fun getVideowidth(): Int {
        if (!isPrepar) return 0
        return mediaPlayer!!.videoWidth
    }

    override fun isPlaying(): Boolean {
        if (!isPrepar) return false
        return mediaPlayer!!.isPlaying
    }

    override fun setVolume(leftVol: Float, rightVol: Float): Boolean {
        if ((leftVol < 0) or (rightVol < 0) or (leftVol > 1) or (rightVol > 1)) return false
        if (isPrepar) mediaPlayer!!.setVolume(leftVol, rightVol)
        return this is IjkMedia
    }

    override fun setLooping(isLooping: Boolean) {
        this.isLooping = isLooping
        mediaPlayer?.isLooping = isLooping
    }

    override fun release() {
        isPrepar = false
        this.surface = null
        if (mediaPlayer != null) {
//            final IMediaPlayer temp = mediaPlayer;
//            new Thread(new Runnable() {
//                @Override
//                public void run() {
//                    if (temp != null) {
//                        temp.release();
//                    }
//                }
//            }).start();
            mediaPlayer!!.release()
        }
        mediaPlayer = null
    }

    /////////////以下MediaPlayer回调//////////////
    override fun onPrepared(iMediaPlayer: IMediaPlayer?) {
        isPrepar = true
        iMediaCallback.onPrepared(this)
    }

    override fun onBufferingUpdate(iMediaPlayer: IMediaPlayer?, i: Int) {
        iMediaCallback.onBufferingUpdate(this, i / 100.0f)
    }

    override fun onCompletion(iMediaPlayer: IMediaPlayer?) {
        iMediaCallback.onCompletion(this)
    }

    override fun onError(iMediaPlayer: IMediaPlayer?, what: Int, extra: Int): Boolean {
        iMediaCallback.onError(this, what, extra)
        isPrepar = false
        return true
    }

    override fun onInfo(iMediaPlayer: IMediaPlayer?, what: Int, extra: Int): Boolean {
        iMediaCallback.onInfo(this, what, extra)
        return false
    }


    override fun onSeekComplete(iMediaPlayer: IMediaPlayer?) {
        iMediaCallback.onSeekComplete(this)
    }

    override fun onVideoSizeChanged(
        iMediaPlayer: IMediaPlayer?,
        width: Int,
        height: Int,
        i2: Int,
        i3: Int
    ) {
        iMediaCallback.onVideoSizeChanged(this, width, height)
    }
}